package model.map;

import java.util.*;

import model.entity.Avatar;

/**
 * Map used by the view to render the game.
 * @author Zachary
 *
 */
public class ViewMap {
	private Map<MapPoint, Queue<String>> tiles;
	private MapPoint renderLocation;
	private MapPoint baseLocation;
	
	private int xDimension;
	private int yDimension;
	
	/**
	 * Constructor for the ViewMap.  
	 * MUST BE THE SAME SIZE AS THE GAMEMAP!!! (it will work otherwise, but won't look right)
	 * @param xDimension
	 * @param yDimension
	 * @param defaultGraphicID
	 * @param avatar
	 */
	public ViewMap(int xDimension, int yDimension, String defaultGraphicID, Avatar avatar){
		this.tiles = new HashMap<MapPoint, Queue<String>>();
		this.baseLocation = avatar.getLocation();
		this.renderLocation = baseLocation;
		
		this.xDimension = xDimension;
		this.yDimension = yDimension;
		
		// initialize the tiles to show the default graphic (black tile)
		for(int i = 0;i<=xDimension;i++){
			for(int j = 0;j<=yDimension;j++){
				Queue<String> defaultGraphic = new LinkedList<String>();
				defaultGraphic.add(defaultGraphicID);
				MapPoint point = new MapPoint(i,j);
				if(MapPoint.isValidLocation(point))	
					tiles.put(new MapPoint( i,j), defaultGraphic);
			}
		}
	}
	
	/**
	 * TESTING
	 */
	public ViewMap(){
		this.xDimension = 40;
		this.yDimension = 40;
		this.renderLocation = new MapPoint(20,20);
		this.baseLocation = renderLocation;
		this.tiles = new HashMap<MapPoint, Queue<String>>();
		for(int i = 0;i<=40;++i){
			for(int j = 0;j<=40;++j){
				MapPoint point = new MapPoint(i,j);
				if(!MapPoint.isValidLocation(point))
					continue;
				Queue<String> renderables = new LinkedList<String>();
				renderables.add("grass");
				if(i == 20 && j == 20)
					renderables.add("NPCs\\medusa1");
				if(i == 21 && j == 21)
					renderables.add("Avatars\\smasher1");
				if(i == 15 && j == 15)
					renderables.add("fire");
				if(i == 18 && j == 20)
					renderables.add("fire");
				if(i == 18 && j == 16)
					renderables.add("mace");
				if(i == 25 && j == 23)
					renderables.add("money");
				pushRenderablesToPoint(renderables,point);
			}
		}
	
	}
	
	/**
	 * Returns whether or not a point is valid.
	 * @param point
	 * @return
	 */
	private boolean validLocation(MapPoint point){
		int xCoord = point.getXCoordinate();
		int yCoord = point.getYCoordinate();
		return xCoord <= this.xDimension && yCoord <= this.yDimension &&
			xCoord >= 0 && yCoord >= 0;
	}
	
	/**
	 * Get graphicObjectIDs at a point.
	 * @param point
	 * @return
	 */
	public Queue<String> getRenderablesFromPoint(MapPoint point){
		Queue<String> ret = null;
		if(validLocation(point))
			ret = tiles.get(point);
		//System.out.println(ret);
		return ret;
	}
	
	/**
	 * Push graphicObjectIDs to a point.
	 * @param newGraphics
	 * @param point
	 */
	public void pushRenderablesToPoint(Queue<String> newGraphics, MapPoint point){
		if(validLocation(point))
			this.tiles.put(point, newGraphics);
	}
	
	/**
	 * Change the renderlocation by a factor of a direction.
	 * @param direction
	 */
	public void incrementScrollLocation(MapPoint direction){
		this.renderLocation = MapPoint.addPoints(direction,renderLocation);
	}
	
	/**
	 * Revert the render location to the base location.
	 */
	public void revertScroll(){
		this.renderLocation = baseLocation;
	}
	
	/**
	 * Set the baselocation to the avatar's location.
	 * @param point
	 */
	public void setAvatarLocation(MapPoint point){
		this.baseLocation = point;
	}
	
	/**
	 * Returns the center point for rendering.
	 * @return
	 */
	public MapPoint getRenderLocation(){
		return this.renderLocation;
	}
	
	/**
	 * Removes the images in the set from the queue.
	 * @param point
	 * @param graphicSet
	 */
	public void removeImageFromQueue(MapPoint point, Set<String> graphicSet){
		Queue<String> images = this.getRenderablesFromPoint(point);
		// remove the duplicate graphic
		for(String s : images){
			if(graphicSet.contains(s))
				images.remove(s);
		}
	}
}
